﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.Win32;
using Q42.Wheels.Api.Nabaztag;

namespace NabaztagDemoApplication
{
    public partial class Form1 : Form
    {
        NabaztagApi nabapi = null;
        protected string serial = "";
        protected string token = "";
        List<String> languages = null;
        protected string currentvoice;

        public Form1()
        {
            InitializeComponent();
            panel1.Visible = false;
            this.Size = new Size(this.Size.Width, 84);
        }

        /// <summary>
        /// Start the bunny and fetch some details about him
        /// </summary>
        /// <param name="serial"></param>
        /// <param name="token"></param>
        protected void initializeBunny(String serial, String token)
        {
            if (nabapi == null)
            {
                /*
                 * initialize API and fetch languages/voices 
                 * 
                 * Assumption: the voices/languages will 
                 * not chance in the time that we use our example application
                 */
                try
                {
                    nabapi = new NabaztagApi(serial, token);
                    languages = nabapi.GetSupportedLanguages();
                    foreach (String language in languages)
                        languagesBox.Items.Add(language);

                    //select first item as default value
                    languagesBox.SelectedIndex = 0;
                }
                catch (Exception ex)
                {
                    nabapi = null;
                    throw ex;
                }
            }
            else
            {
                nabapi.Serial = serial;
                nabapi.Token = token;
            }
            
            //init status dialog
            button4_Click(this, null);
        }

        private void languagesBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            //load voices list with new voices
            string currentlanguage = (String) languagesBox.SelectedItem;
            if (currentlanguage == null)
                return;//nothing changes
            List<String> voices = nabapi.GetSupportedVoices(currentlanguage);

            voicesBox.Items.Clear();

            voices.Sort();//no clue what happens :)
            foreach (String voice in voices)
                voicesBox.Items.Add(voice);

            //select first item
            voicesBox.SelectedIndex = 0;
        }

        private void voicesBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            //mark current voice in application
            currentvoice = (String)voicesBox.SelectedItem;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            String texttosay = textBox2.Text;
            nabapi.SendAction(new TextToSpeechAction(texttosay, currentvoice));
        }

        private void button3_Click(object sender, EventArgs e)
        {
            Int16 leftEarPosition;
            Int16 rightEarPosition;
            
            if (!Int16.TryParse(textBox3.Text, out leftEarPosition))
            {
                MessageBox.Show("Left ear position should be integer");
                return;
            }
            if (!Int16.TryParse(textBox4.Text, out rightEarPosition))
            {
                MessageBox.Show("Right ear position should be integer");
                return;
            }
            try
            {
                nabapi.SendAction(new EarsAction(leftEarPosition, rightEarPosition));
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void button4_Click(object sender, EventArgs e)
        {
            /*
             * provide some information about the API on screen
             */
            label6.Text = nabapi.IsSleeping ? "Bunny is sleeping" : "Bunny is awake";
            label7.Text = "Bunny name: " + nabapi.Name;
            label8.Text = "Version: " + nabapi.Version.ToString();
            label9.Text = "Timezone: " + nabapi.GetTimezone();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            nabapi.IsSleeping = true;
        }

        private void button6_Click(object sender, EventArgs e)
        {
            nabapi.IsSleeping = false;
        }

        private void button7_Click(object sender, EventArgs e)
        {
            /*
             * see http://code.google.com/p/q42nabaztagapi/wiki/ChoreographysExplained
             * or look at the source how an choreography is build up.
             */
            ChoreographyAction action = new ChoreographyAction("lechoreographytest", 10);
            action.ChoreographyParts.Add(new LedChoreographyPart(5, LedChoreographyPart.Leds.BottomLed, 255, 0, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(10, LedChoreographyPart.Leds.TopLed, 0, 255, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(15, LedChoreographyPart.Leds.LeftLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(20, LedChoreographyPart.Leds.RightLed, 255, 0, 255));

            action.ChoreographyParts.Add(new LedChoreographyPart(25, LedChoreographyPart.Leds.BottomLed, 255, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(30, LedChoreographyPart.Leds.TopLed, 255, 255, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(35, LedChoreographyPart.Leds.LeftLed, 255, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(40, LedChoreographyPart.Leds.RightLed, 0, 255, 255));
            nabapi.SendAction(action);
        }

        private void button8_Click(object sender, EventArgs e)
        {
            /*
             * see http://code.google.com/p/q42nabaztagapi/wiki/ChoreographysExplained
             * or look at the source how an choreography is build up.
             */
            ChoreographyAction action = new ChoreographyAction("earchoreographytest", 10);
            action.ChoreographyParts.Add(new LedChoreographyPart(5, LedChoreographyPart.Leds.BottomLed, 255, 0, 0));
            action.ChoreographyParts.Add(new EarChoreographyPart(5, EarChoreographyPart.Ears.LeftEar, 60, EarChoreographyPart.RotationDirection.BackwardDirection));
            action.ChoreographyParts.Add(new EarChoreographyPart(5, EarChoreographyPart.Ears.RightEar, 60, EarChoreographyPart.RotationDirection.BackwardDirection));


            action.ChoreographyParts.Add(new LedChoreographyPart(15, LedChoreographyPart.Leds.LeftLed, 0, 0, 255));
            action.ChoreographyParts.Add(new EarChoreographyPart(15, EarChoreographyPart.Ears.LeftEar, 60, EarChoreographyPart.RotationDirection.ForwardDirection));
            action.ChoreographyParts.Add(new EarChoreographyPart(15, EarChoreographyPart.Ears.RightEar, 60, EarChoreographyPart.RotationDirection.ForwardDirection));

            action.ChoreographyParts.Add(new LedChoreographyPart(40, LedChoreographyPart.Leds.BottomLed, 255, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(40, LedChoreographyPart.Leds.TopLed, 255, 255, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(40, LedChoreographyPart.Leds.LeftLed, 255, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(40, LedChoreographyPart.Leds.RightLed, 0, 255, 255));

            nabapi.SendAction(action);
        }

        private void button9_Click(object sender, EventArgs e)
        {
            nabapi.SendAction(new TextToSpeechAction("This is an message, followed by some light and ear movement", "UK-Rachel"));

            ChoreographyAction action = new ChoreographyAction("buildsuccess", 3);

            //turn ears to 'yay position'
            action.ChoreographyParts.Add(new EarChoreographyPart(0, EarChoreographyPart.Ears.LeftEar, 0, EarChoreographyPart.RotationDirection.ForwardDirection));
            action.ChoreographyParts.Add(new EarChoreographyPart(0, EarChoreographyPart.Ears.RightEar, 0, EarChoreographyPart.RotationDirection.ForwardDirection));

            //all lights red
            action.ChoreographyParts.Add(new LedChoreographyPart(6, LedChoreographyPart.Leds.TopLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(12, LedChoreographyPart.Leds.LeftLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(18, LedChoreographyPart.Leds.MiddleLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(21, LedChoreographyPart.Leds.RightLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(24, LedChoreographyPart.Leds.BottomLed, 0, 0, 255));

            //all lights off
            action.ChoreographyParts.Add(new LedChoreographyPart(27, LedChoreographyPart.Leds.TopLed, 0, 0, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(27, LedChoreographyPart.Leds.LeftLed, 0, 0, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(27, LedChoreographyPart.Leds.MiddleLed, 0, 0, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(27, LedChoreographyPart.Leds.RightLed, 0, 0, 0));
            action.ChoreographyParts.Add(new LedChoreographyPart(27, LedChoreographyPart.Leds.BottomLed, 0, 0, 0));

            //all lights on again
            action.ChoreographyParts.Add(new LedChoreographyPart(30, LedChoreographyPart.Leds.TopLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(30, LedChoreographyPart.Leds.LeftLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(30, LedChoreographyPart.Leds.MiddleLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(30, LedChoreographyPart.Leds.RightLed, 0, 0, 255));
            action.ChoreographyParts.Add(new LedChoreographyPart(30, LedChoreographyPart.Leds.BottomLed, 0, 0, 255));

            /*
             * keep all lights on for quite some time because it seems default behaviour is to 
             * keep playing last choreographypart untill the choreography ends or an other part uses the same object
             */
            action.ChoreographyParts.Add(new LedChoreographyPart(60, LedChoreographyPart.Leds.BottomLed, 0, 0, 255));

            nabapi.SendAction(action);
        }

        private void button10_Click(object sender, EventArgs e)
        {
            Int16 leftEarPosition;
            Int16 rightEarPosition;

            if (!Int16.TryParse(textBox6.Text, out leftEarPosition))
            {
                MessageBox.Show("Left ear position should be integer");
                return;
            }
            if (!Int16.TryParse(textBox5.Text, out rightEarPosition))
            {
                MessageBox.Show("Right ear position should be integer");
                return;
            }

            String texttosay = textBox7.Text;
            try{
                List<NabaztagAction> actions = new List<NabaztagAction>();
                actions.Add(new TextToSpeechAction(texttosay, currentvoice));
                actions.Add(new EarsAction(leftEarPosition, rightEarPosition));
                nabapi.SendActionList(actions);
            }
            catch(Exception ex){
                MessageBox.Show(ex.Message);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            token = textBox1.Text;
            serial = textBox8.Text;

            if (token.Equals(string.Empty) || serial.Equals(string.Empty))
            {
                MessageBox.Show("Serial and token need to be provided");
                return;
            }

            //fetch voices, initialize bunny
            try
            {
                initializeBunny(serial, token);

                //show controls
                panel1.Visible = true;
                this.Size = new Size(this.Size.Width, 500);
            }
            catch (Exception ex)
            {
                MessageBox.Show("error while connection to bunny service: " + ex.Message);
            }
        }

        #region link to Q42 website
        private void pictureBox1_Click(object sender, EventArgs e)
        {
            //go to Q42 website (Dutch!)
            string key = @"htmlfile\shell\open\command";
            RegistryKey registryKey =
            Registry.ClassesRoot.OpenSubKey(key, false);
            Process.Start((((string)registryKey.GetValue(null, null)).Split('"')[1]), "http://www.q42.nl/");
        }

        private void pictureBox1_MouseHover(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Hand;
        }
        private void pictureBox1_MouseLeave(object sender, EventArgs e)
        {
            this.Cursor = Cursors.Default;
        }
        #endregion
    }
}
